#include "StdAfx.h"
#include "Note.h"

CNote::CNote(CppSQLite3DB* pdb, HINSTANCE hInst, HMENU hMenu, 
			 COLORREF color, COLORREF* colors, BOOL autoLoad):
		id(0),dirty(FALSE),visible(FALSE),topmost(FALSE),poschanged(FALSE)
{
	this->pdb = pdb;
	this->hInst = hInst;
	this->hMenu = hMenu;
	this->colors = colors;
	this->color = color;
}
CNote::~CNote(void)
{
	delete(win);
}
void CNote::Update()
{
}
void CNote::Reload()
{
}
void CNote::Show()
{
	win = new CNoteWindow(this);

	vector<tstring> rc;
	boost::algorithm::split(rc, position, boost::algorithm::is_any_of(_T(",")));
	if(rc.size() != 4)
	{
		win->CreateEx(0, 0, 160, 120, 0, hInst);
		win->CenterWindow();
	}
	else
	{
		int left = boost::lexical_cast<int>(rc[0]);
		int top = boost::lexical_cast<int>(rc[1]);
		int right = boost::lexical_cast<int>(rc[2]);
		int bottom = boost::lexical_cast<int>(rc[3]);

		int screenx = GetSystemMetrics(SM_CXSCREEN);
		int screeny = GetSystemMetrics(SM_CYSCREEN);

		int width = right - left;
		width = (width < 30 || width > 300) ? 160 : width;
		int height = bottom - top;
		height = (height < 20 || height > 200) ? 120 : height;

		if(left < 0) {left = 0;}
		if(top < 0) {top = 0;}
		if(right > screenx) {left = screenx - width;}
		if(bottom > screeny) {top = screeny - height;}

		right = left + width;
		bottom = top + height;

		win->CreateEx(left, top, right-left, bottom-top, 0, hInst);
	}
	GetPosition();
	dirty = FALSE;
	ShowWindow(win->m_hWnd, SW_SHOW);
	SetForegroundWindow(win->m_hWnd);
}
void CNote::MakeTopmost(BOOL top)
{
	if(win->m_hWnd)
	{
		if(top)
			SetWindowPos(win->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
		else
			SetWindowPos(win->m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
	}
}
void CNote::Save()
{
	GetPosition();
	if(dirty || poschanged)
	{
		tstringstream sql;
		sql.str(_T(""));
		tstring bd;
		bd = body;
		boost::algorithm::replace_all(bd, _T("\'"), _T("\'\'"));
		try
		{
			if(id == 0)
			{
				sql << "INSERT INTO notes(body, created_at, position, color, topmost) VALUES('"
					<< bd << "','" << created_at << "','" << position << "','" << color << "','" << topmost << "' );";
				pdb->execQuery(sql.str().c_str());
				id = pdb->lastRowId();
			}
			else
			{
				std::time_t now = time(0);
				sql << "UPDATE notes SET body = '" << bd << "', modified_at = '" << now 
					<< "', color = '" << color << "', topmost = '" << topmost 
					<< "', position = '" << position <<"' WHERE id=" << id << ";";
				pdb->execQuery(sql.str().c_str());
			}
		}
		catch (CppSQLite3Exception& e)
		{
			win->Msgbox(e.errorMessage());
		}
		dirty = FALSE;
		obody = body;
	}
}
void CNote::Revert()
{
	if(dirty && win->Msgbox(_T("Note not saved. Revert?"), _T("Very Notes"), MB_YESNO | MB_ICONQUESTION) == IDYES)
	{
		body = obody;
		dirty = FALSE;
		SetWindowText(win->m_hWndStatic, body.c_str());
	}	
}
void CNote::Delete()
{
	if(win->Msgbox(_T("Are you sure?"), _T("Very Notes"), MB_YESNO | MB_ICONQUESTION) == IDYES)
	{
		
	}
}
void CNote::Hide()
{
	if(win->m_hWnd)
	{
		if(dirty)
		{
			int r = win->Msgbox(_T("Note not saved. Save?"), _T("Very Notes"), MB_YESNOCANCEL | MB_ICONQUESTION);
			if(r == IDYES) Save();
			else if(r == IDCANCEL) return;
		}
		SendMessage(win->m_hWnd, WM_DESTROY, 0, 0);
	}
}
void CNote::GetPosition()
{
	if(IsWindow(win->m_hWnd))
	{
		RECT rc;
		GetWindowRect(win->m_hWnd, &rc);
		tstringstream ss;
		ss << rc.left << "," << rc.top << "," << rc.right << "," << rc.bottom;
		position = ss.str();
		poschanged = TRUE;
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////
CNoteMgr::CNoteMgr(CppSQLite3DB* pdb, HINSTANCE hInst)
{
	this->pdb = pdb;
	this->m_hInst = hInst;

	m_hMenu = CreatePopupMenu();

	AppendMenu(m_hMenu, MF_STRING, IDMI_NOTE_SAVE, _T("&Save"));
	AppendMenu(m_hMenu, MF_STRING, IDMI_NOTE_TOPMOST, _T("&Topmost"));
	AppendMenu(m_hMenu, MF_STRING, IDMI_NOTE_REVERT, _T("&Revert"));
	AppendMenu(m_hMenu, MF_STRING, IDMI_NOTE_HIDE, _T("&Hide"));
	AppendMenu(m_hMenu, MF_SEPARATOR, NULL, NULL);
	AppendMenu(m_hMenu, MF_OWNERDRAW, IDMI_NOTE_COLOR0, NULL);
	AppendMenu(m_hMenu, MF_OWNERDRAW, IDMI_NOTE_COLOR1, NULL);
	AppendMenu(m_hMenu, MF_OWNERDRAW, IDMI_NOTE_COLOR2, NULL);
	AppendMenu(m_hMenu, MF_OWNERDRAW, IDMI_NOTE_COLOR3, NULL);
	AppendMenu(m_hMenu, MF_OWNERDRAW, IDMI_NOTE_COLOR4, NULL);
	AppendMenu(m_hMenu, MF_SEPARATOR, NULL, NULL);
	AppendMenu(m_hMenu, MF_STRING, IDMI_NOTE_DELETE, _T("&Delete"));

	color = 0x0099FFFF;

	colors[0] = 0x0099FFFF;
	colors[1] = 0x00FFCC99;
	colors[2] = 0x00CC99FF;
	colors[3] = 0x0099CCFF;
	colors[4] = 0x00CCFFCC;
}

CNoteMgr::~CNoteMgr(void)
{
	vector<CNote*>::iterator it;
	for(it=m_notesList.begin(); it!=m_notesList.end(); ++it)
	{
		delete(*it);
	}
}

CNote* CNoteMgr::Create()
{
	CNote *nd = new CNote(pdb, m_hInst, m_hMenu, color, colors);
	nd->Show();
	m_notesList.push_back(nd);
	return nd;
}

void CNoteMgr::Load()
{
	try
	{
		CppSQLite3Query q = pdb->execQuery(_T("SELECT * FROM notes;"));
		while(!q.eof())
		{
			CNote *nd = new CNote(pdb, m_hInst, m_hMenu, color, colors);

			nd->id = boost::lexical_cast<int>(q.fieldValue(_T("id")));
			nd->body = q.fieldValue(_T("body"));
			nd->position = q.fieldValue(_T("position"));

			nd->color = q.getIntField(_T("color"));
			nd->topmost = q.getIntField(_T("topmost"));

			nd->created_at = (time_t)q.getIntField(_T("created_at"));
			nd->modified_at = (time_t)q.getIntField(_T("modified_at"));
			nd->Show();
			m_notesList.push_back(nd);
			q.nextRow();
		}
	}
	catch (CppSQLite3Exception& e)
	{
		MessageBox(0, e.errorMessage(), 0, MB_OK);
	}
}

void CNoteMgr::Save()
{
	vector<CNote*>::iterator it;
	for(it = m_notesList.begin(); it != m_notesList.end(); ++it)
	{
		(*it)->Save();
	}
}

void CNoteMgr::Delete()
{
}

void CNoteMgr::Show(BOOL visible)
{
}

void CNoteMgr::MakeTopmost(BOOL top)
{
	vector<CNote*>::iterator it;
	for(it = m_notesList.begin(); it != m_notesList.end(); ++it)
	{
		(*it)->MakeTopmost(top);
	}
}
